package cn.sciento.iam.saas.domain.service.impl;

import cn.sciento.boot.platform.code.builder.CodeRuleBuilder;
import cn.sciento.core.base.BaseConstants;
import cn.sciento.core.exception.CommonException;
import cn.sciento.iam.domain.entity.Tenant;
import cn.sciento.iam.domain.repository.TenantRepository;
import cn.sciento.iam.saas.domain.service.TenantCoreService;
import cn.sciento.iam.saas.domain.service.TenantEventBus;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

public class TenantCoreServiceImpl implements TenantCoreService {
  private static final Logger LOGGER = LoggerFactory.getLogger(TenantCoreServiceImpl.class);
  
  @Autowired
  private TenantEventBus tenantEventBus;
  
  @Autowired
  private TenantRepository tenantRepository;
  
  @Autowired
  private CodeRuleBuilder codeRuleBuilder;
  
  @Override
  public Tenant createTenant(Tenant tenant) {
    LOGGER.info("Start create tenant, tenant is {}", tenant);
    initTenant(tenant);
    validateTenant(tenant);
    beforeCreateTenant(tenant);
    this.tenantRepository.insertSelective(tenant);
    LOGGER.info("[TenantInit - Num={}] -> {}", tenant.getTenantNum(), tenant);
    afterCreateTenant(tenant);
    LOGGER.info("Finish create tenant, tenant is {}", tenant);
    return tenant;
  }
  
  @Override
  public Tenant updateTenant(Long tenantId, Tenant tenant) {
    LOGGER.info("Start update tenant, tenant is {}", tenant);
    validateTenant(tenant);
    Tenant exist = this.tenantRepository.selectByPrimaryKey(tenantId);
    Assert.notNull(exist, "error.data_not_exists");
    beforeUpdateTenant(tenant);
    this.tenantRepository.updateOptional(tenant, "enabledFlag", "tenantName", "limitUserQty");
    afterUpdateTenant(tenant);
    LOGGER.info("Finish update tenant, tenant is {}", tenant);
    return tenant;
  }
  
  protected void initTenant(Tenant tenant) {
    if (StringUtils.isBlank(tenant.getTenantNum())) {
      String tenantNum = this.codeRuleBuilder.generateCode("T", BaseConstants.DEFAULT_TENANT_ID, "HPFM.TENANT", "GLOBAL", "GLOBAL", null);
      tenant.setTenantNum(tenantNum);
    } 
    if (tenant.getEnabledFlag() == null) {
      tenant.setEnabledFlag(BaseConstants.Flag.YES);
    }
  }
  
  protected void validateTenant(Tenant tenant) {
    if (tenant.getTenantId() == null && 
      this.tenantRepository.countByTenantNum(tenant.getTenantNum()) > 0) {
      throw new CommonException("hiam.warn.tenant.numExists");
    }
  }
  
  protected void beforeCreateTenant(Tenant tenant) {}
  
  protected void afterCreateTenant(Tenant tenant) {
    this.tenantEventBus.notifyTenantCreate(tenant);
  }
  
  protected void beforeUpdateTenant(Tenant tenant) {}
  
  protected void afterUpdateTenant(Tenant tenant) {
    this.tenantEventBus.notifyTenantUpdate(tenant);
  }
}
